const Lang = imports.lang;
const Signals = imports.signals;
const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Pango = imports.gi.Pango;
const St = imports.gi.St;
this._dialog.open();
},
- _onAskPassword: function(op, message) {
+ _onAskPassword: function(op, message, defaultUser, defaultDomain, flags) {
if (this._existingDialog) {
this._dialog = this._existingDialog;
this._dialog.reaskPassword();
} else {
- this._dialog = new ShellMountPasswordDialog(message, this._gicon);
+ this._dialog = new ShellMountPasswordDialog(message, this._gicon, flags);
}
this._dialogId = this._dialog.connect('response', Lang.bind(this,
function(object, choice, password, remember) {
- if (choice == '-1') {
+ if (choice == -1) {
this.mountOp.reply(Gio.MountOperationResult.ABORTED);
} else {
if (remember)
Name: 'ShellMountPasswordDialog',
Extends: ModalDialog.ModalDialog,
- _init: function(message, gicon) {
+ _init: function(message, gicon, flags) {
let strings = message.split('\n');
this.parent({ styleClass: 'prompt-dialog' });
this._errorMessageLabel.hide();
this._messageBox.add(this._errorMessageLabel);
- this._rememberChoice = new CheckBox.CheckBox();
- this._rememberChoice.getLabelActor().text = _("Remember Passphrase");
- this._rememberChoice.actor.checked = true;
- this._messageBox.add(this._rememberChoice.actor);
+ if (flags & Gio.AskPasswordFlags.SAVING_SUPPORTED) {
+ this._rememberChoice = new CheckBox.CheckBox();
+ this._rememberChoice.getLabelActor().text = _("Remember Passphrase");
+ this._rememberChoice.actor.checked = true;
+ this._messageBox.add(this._rememberChoice.actor);
+ } else {
+ this._rememberChoice = null;
+ }
let buttons = [{ label: _("Cancel"),
action: Lang.bind(this, this._onCancelButton),
_onEntryActivate: function() {
this.emit('response', 1,
this._passwordEntry.get_text(),
+ this._rememberChoice &&
this._rememberChoice.actor.checked);
}
});
}
});
Signals.addSignalMethods(ShellProcessesDialog.prototype);
+
+const GnomeShellMountOpIface = <interface name="org.Gtk.MountOperationHandler">
+<method name="AskPassword">
+ <arg type="s" direction="in" name="object_id"/>
+ <arg type="s" direction="in" name="message"/>
+ <arg type="s" direction="in" name="icon_name"/>
+ <arg type="s" direction="in" name="default_user"/>
+ <arg type="s" direction="in" name="default_domain"/>
+ <arg type="u" direction="in" name="flags"/>
+ <arg type="u" direction="out" name="response"/>
+ <arg type="a{sv}" direction="out" name="response_details"/>
+</method>
+<method name="AskQuestion">
+ <arg type="s" direction="in" name="object_id"/>
+ <arg type="s" direction="in" name="message"/>
+ <arg type="s" direction="in" name="icon_name"/>
+ <arg type="as" direction="in" name="choices"/>
+ <arg type="u" direction="out" name="response"/>
+ <arg type="a{sv}" direction="out" name="response_details"/>
+</method>
+<method name="ShowProcesses">
+ <arg type="s" direction="in" name="object_id"/>
+ <arg type="s" direction="in" name="message"/>
+ <arg type="s" direction="in" name="icon_name"/>
+ <arg type="ai" direction="in" name="application_pids"/>
+ <arg type="as" direction="in" name="choices"/>
+ <arg type="u" direction="out" name="response"/>
+ <arg type="a{sv}" direction="out" name="response_details"/>
+</method>
+<method name="Close"/>
+</interface>;
+
+const ShellMountOperationType = {
+ NONE: 0,
+ ASK_PASSWORD: 1,
+ ASK_QUESTION: 2,
+ SHOW_PROCESSES: 3
+};
+
+const GnomeShellMountOpHandler = new Lang.Class({
+ Name: 'GnomeShellMountOpHandler',
+
+ _init: function() {
+ this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellMountOpIface, this);
+ this._dbusImpl.export(Gio.DBus.session, '/org/gtk/MountOperationHandler');
+ Gio.bus_own_name_on_connection(Gio.DBus.session, 'org.gtk.MountOperationHandler',
+ Gio.BusNameOwnerFlags.REPLACE, null, null);
+
+ this._dialog = null;
+ this._volumeMonitor = Gio.VolumeMonitor.get();
+
+ this._ensureEmptyRequest();
+ },
+
+ _ensureEmptyRequest: function() {
+ this._currentId = null;
+ this._currentInvocation = null;
+ this._currentType = ShellMountOperationType.NONE;
+ },
+
+ _clearCurrentRequest: function(response, details) {
+ if (this._currentInvocation) {
+ this._currentInvocation.return_value(
+ GLib.Variant.new('(ua{sv})', [response, details]));
+ }
+
+ this._ensureEmptyRequest();
+ },
+
+ _setCurrentRequest: function(invocation, id, type) {
+ let oldId = this._currentId;
+ let oldType = this._currentType;
+ let requestId = id + '@' + invocation.get_sender();
+
+ this._clearCurrentRequest(Gio.MountOperationResult.UNHANDLED, {});
+
+ this._currentInvocation = invocation;
+ this._currentId = requestId;
+ this._currentType = type;
+
+ if (this._dialog && (oldId == requestId) && (oldType == type))
+ return true;
+
+ return false;
+ },
+
+ _closeDialog: function() {
+ if (this._dialog) {
+ this._dialog.close();
+ this._dialog = null;
+ }
+ },
+
+ _createGIcon: function(iconName) {
+ let realIconName = iconName ? iconName : 'drive-harddisk';
+ return new Gio.ThemedIcon({ name: realIconName,
+ use_default_fallbacks: true });
+ },
+
+ /**
+ * AskPassword:
+ * @id: an opaque ID identifying the object for which the operation is requested
+ * The ID must be unique in the context of the calling process.
+ * @message: the message to display
+ * @icon_name: the name of an icon to display
+ * @default_user: the default username for display
+ * @default_domain: the default domain for display
+ * @flags: a set of GAskPasswordFlags
+ * @response: a GMountOperationResult
+ * @response_details: a dictionary containing the response details as
+ * entered by the user. The dictionary MAY contain the following properties:
+ * - "password" -> (s): a password to be used to complete the mount operation
+ * - "password_save" -> (u): a GPasswordSave
+ *
+ * The dialog will stay visible until clients call the Close() method, or
+ * another dialog becomes visible.
+ * Calling AskPassword again for the same id will have the effect to clear
+ * the existing dialog and update it with a message indicating the previous
+ * attempt went wrong.
+ */
+ AskPasswordAsync: function(params, invocation) {
+ let [id, message, iconName, defaultUser, defaultDomain, flags] = params;
+
+ if (this._setCurrentRequest(invocation, id, ShellMountOperationType.ASK_PASSWORD)) {
+ this._dialog.reaskPassword();
+ return;
+ }
+
+ this._closeDialog();
+
+ this._dialog = new ShellMountPasswordDialog(message, this._createGIcon(iconName), flags);
+ this._dialog.connect('response', Lang.bind(this,
+ function(object, choice, password, remember) {
+ let details = {};
+ let response;
+
+ if (choice == -1) {
+ response = Gio.MountOperationResult.ABORTED;
+ } else {
+ response = Gio.MountOperationResult.HANDLED;
+
+ let passSave = remember ? Gio.PasswordSave.PERMANENTLY : Gio.PasswordSave.NEVER;
+ details['password_save'] = GLib.Variant.new('u', passSave);
+ details['password'] = GLib.Variant.new('s', password);
+ }
+
+ this._clearCurrentRequest(response, details);
+ }));
+ this._dialog.open();
+ },
+
+ /**
+ * AskQuestion:
+ * @id: an opaque ID identifying the object for which the operation is requested
+ * The ID must be unique in the context of the calling process.
+ * @message: the message to display
+ * @icon_name: the name of an icon to display
+ * @choices: an array of choice strings
+ * GetResponse:
+ * @response: a GMountOperationResult
+ * @response_details: a dictionary containing the response details as
+ * entered by the user. The dictionary MAY contain the following properties:
+ * - "choice" -> (i): the chosen answer among the array of strings passed in
+ *
+ * The dialog will stay visible until clients call the Close() method, or
+ * another dialog becomes visible.
+ * Calling AskQuestion again for the same id will have the effect to clear
+ * update the dialog with the new question.
+ */
+ AskQuestionAsync: function(params, invocation) {
+ let [id, message, iconName, choices] = params;
+
+ if (this._setCurrentRequest(invocation, id, ShellMountOperationType.ASK_QUESTION)) {
+ this._dialog.update(message, choices);
+ return;
+ }
+
+ this._closeDialog();
+
+ this._dialog = new ShellMountQuestionDialog(this._createGIcon(iconName), message);
+ this._dialog.connect('response', Lang.bind(this,
+ function(object, choice) {
+ this._clearCurrentRequest(Gio.MountOperationResult.HANDLED,
+ { choice: GLib.Variant.new('i', choice) });
+ }));
+
+ this._dialog.update(message, choices);
+ this._dialog.open();
+ },
+
+ /**
+ * ShowProcesses:
+ * @id: an opaque ID identifying the object for which the operation is requested
+ * The ID must be unique in the context of the calling process.
+ * @message: the message to display
+ * @icon_name: the name of an icon to display
+ * @application_pids: the PIDs of the applications to display
+ * @choices: an array of choice strings
+ * @response: a GMountOperationResult
+ * @response_details: a dictionary containing the response details as
+ * entered by the user. The dictionary MAY contain the following properties:
+ * - "choice" -> (i): the chosen answer among the array of strings passed in
+ *
+ * The dialog will stay visible until clients call the Close() method, or
+ * another dialog becomes visible.
+ * Calling ShowProcesses again for the same id will have the effect to clear
+ * the existing dialog and update it with the new message and the new list
+ * of processes.
+ */
+ ShowProcessesAsync: function(params, invocation) {
+ let [id, message, iconName, applicationPids, choices] = params;
+
+ if (this._setCurrentRequest(invocation, id, ShellMountOperationType.SHOW_PROCESSES)) {
+ this._dialog.update(message, applicationPids, choices);
+ return;
+ }
+
+ this._closeDialog();
+
+ this._dialog = new ShellProcessesDialog(this._createGIcon(iconName));
+ this._dialog.connect('response', Lang.bind(this,
+ function(object, choice) {
+ let response;
+ let details = {};
+
+ if (choice == -1) {
+ response = Gio.MountOperationResult.ABORTED;
+ } else {
+ response = Gio.MountOperationResult.HANDLED;
+ details['choice'] = GLib.Variant.new('i', choice);
+ }
+
+ this._clearCurrentRequest(response, details);
+ }));
+
+ this._dialog.update(message, applicationPids, choices);
+ this._dialog.open();
+ },
+
+ /**
+ * Close:
+ *
+ * Closes a dialog previously opened by AskPassword, AskQuestion or ShowProcesses.
+ * If no dialog is open, does nothing.
+ */
+ Close: function(params, invocation) {
+ this._clearCurrentRequest(Gio.MountOperationResult.UNHANDLED, {});
+ this._closeDialog();
+ }
+});